bitkeeper revision 1.1159.38.1 (41231e93omwWBjFZGIgG3ek6UMbDYA)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Wed, 18 Aug 2004 09:17:07 +0000 (09:17 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Wed, 18 Aug 2004 09:17:07 +0000 (09:17 +0000)
Refactor device setup code so that the devices do more of
the messaging.

tools/python/xen/lowlevel/xu/xu.c
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/SrvDomain.py
tools/python/xen/xend/server/blkif.py
tools/python/xen/xend/server/channel.py
tools/python/xen/xend/server/controller.py
tools/python/xen/xend/server/messages.py
tools/python/xen/xend/server/netif.py

index d403099cec33ed90e3b8ad0d82546f7e8c80387d..3b078e7d33c020b3640d20647a1f7d7c12882ca1 100644 (file)
@@ -426,6 +426,12 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
         C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
         C2P(netif_fe_interface_status_changed_t, status, Int, Long);
         C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
+        C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long);
+        C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long);
+        C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long);
+        C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long);
+        C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long);
+        C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long);
         return dict;
     case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
         C2P(netif_fe_driver_status_changed_t, status,        Int, Long);
index 602575d0ba293f9a1540a169ca6fc851a0a0d8aa..d2bff39b04a3adca33a1cea5b4f3a06144add179 100644 (file)
@@ -1074,8 +1074,8 @@ def vm_dev_vif(vm, val, index):
     @param index:     vif index
     @return: deferred
     """
-    if vm.netif_backend:
-        raise VmError('vif: vif in netif backend domain')
+    #if vm.netif_backend:
+    #    raise VmError('vif: vif in netif backend domain')
     vif = vm.next_device_index('vif')
     vmac = sxp.child_value(val, "mac")
     backend = vm.get_device_backend('vif')
@@ -1098,8 +1098,8 @@ def vm_dev_vbd(vm, val, index):
     @param index:     vbd index
     @return: deferred
     """
-    if vm.blkif_backend:
-        raise VmError('vbd: vbd in blkif backend domain')
+    #if vm.blkif_backend:
+    #    raise VmError('vbd: vbd in blkif backend domain')
     uname = sxp.child_value(val, 'uname')
     if not uname:
         raise VmError('vbd: Missing uname')
index aed8fd7e57848e598012ba74edadb8c35ec59318..50aa355e62d2db29e8985bbf35fc0812c17ef3e4 100644 (file)
@@ -48,7 +48,7 @@ class SrvDomain(SrvDir):
         fn = FormFn(self.xd.domain_shutdown,
                     [['dom', 'str'],
                      ['reason', 'str']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         req.setResponseCode(http.ACCEPTED)
         req.setHeader("Location", "%s/.." % req.prePathURL())
         return val
@@ -57,7 +57,7 @@ class SrvDomain(SrvDir):
         fn = FormFn(self.xd.domain_destroy,
                     [['dom', 'str'],
                      ['reason', 'str']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         req.setHeader("Location", "%s/.." % req.prePathURL())
         return val
 
@@ -65,7 +65,7 @@ class SrvDomain(SrvDir):
         fn = FormFn(self.xd.domain_save,
                     [['dom', 'str'],
                      ['file', 'str']])
-        deferred = fn(req.args, {'dom': self.dom.name})
+        deferred = fn(req.args, {'dom': self.dom.id})
         deferred.addCallback(self._op_save_cb, req)
         deferred.addErrback(self._op_save_err, req)
         return deferred
@@ -81,7 +81,7 @@ class SrvDomain(SrvDir):
         fn = FormFn(self.xd.domain_migrate,
                     [['dom', 'str'],
                      ['destination', 'str']])
-        deferred = fn(req.args, {'dom': self.dom.name})
+        deferred = fn(req.args, {'dom': self.dom.id})
         print 'op_migrate>', deferred
         deferred.addCallback(self._op_migrate_cb, req)
         deferred.addErrback(self._op_migrate_err, req)
@@ -107,7 +107,7 @@ class SrvDomain(SrvDir):
         fn = FormFn(self.xd.domain_pincpu,
                     [['dom', 'str'],
                      ['cpu', 'int']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
 
     def op_cpu_bvt_set(self, op, req):
@@ -118,7 +118,7 @@ class SrvDomain(SrvDir):
                      ['warpvalue', 'int'],
                      ['warpl', 'long'],
                      ['warpu', 'long']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
     
     def op_cpu_fbvt_set(self, op, req):
@@ -128,7 +128,7 @@ class SrvDomain(SrvDir):
                      ['warp', 'int'],
                      ['warpl', 'int'],
                      ['warpu', 'int']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
 
     def op_cpu_atropos_set(self, op, req):
@@ -138,21 +138,21 @@ class SrvDomain(SrvDir):
                      ['slice', 'int'],
                      ['latency', 'int'],
                      ['xtratime', 'int']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
 
     def op_maxmem_set(self, op, req):
         fn = FormFn(self.xd.domain_maxmem_set,
                     [['dom', 'str'],
                      ['memory', 'int']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
 
     def op_device_create(self, op, req):
         fn = FormFn(self.xd.domain_device_create,
                     [['dom', 'str'],
                      ['config', 'sxpr']])
-        d = fn(req.args, {'dom': self.dom.name})
+        d = fn(req.args, {'dom': self.dom.id})
         return d
 
     def op_device_destroy(self, op, req):
@@ -160,29 +160,29 @@ class SrvDomain(SrvDir):
                     [['dom', 'str'],
                      ['type', 'str'],
                      ['idx', 'str']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
                 
     def op_vifs(self, op, req):
-        devs = self.xd.domain_vif_ls(self.dom.name)
+        devs = self.xd.domain_vif_ls(self.dom.id)
         return [ dev.sxpr() for dev in devs ]
 
     def op_vif(self, op, req):
         fn = FormFn(self.xd.domain_vif_get,
                     [['dom', 'str'],
                      ['vif', 'str']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
 
     def op_vbds(self, op, req):
-        devs = self.xd.domain_vbd_ls(self.dom.name)
+        devs = self.xd.domain_vbd_ls(self.dom.id)
         return [ dev.sxpr() for dev in devs ]
 
     def op_vbd(self, op, req):
         fn = FormFn(self.xd.domain_vbd_get,
                     [['dom', 'str'],
                      ['vbd', 'str']])
-        val = fn(req.args, {'dom': self.dom.name})
+        val = fn(req.args, {'dom': self.dom.id})
         return val
 
     def render_POST(self, req):
index bea848bfcf59ec4ab424102cd0b929da15e30ca2..c142e59da86d3e0c84aa48b19333200e39f2a218 100755 (executable)
@@ -22,74 +22,7 @@ class BlkifBackendController(controller.BackendController):
         self.addMethod(CMSG_BLKIF_BE,
                        CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
                        self.recv_be_driver_status_changed)
-        self.attached = 1
         self.registerChannel()
-        
-    def respond_be_create(self, msg, d):
-        """Response handler for a be_create message.
-        Calls I{d} with the block interface created.
-
-        @param msg: message
-        @type  msg: xu message
-        @param d: deferred to call
-        @type  d: Deferred
-        """
-        val = unpackMsg('blkif_be_create_t', msg)
-        blkif = self.factory.getInstanceByDom(val['domid'])
-        d.callback(blkif)
-
-    def respond_be_connect(self, msg):
-        """Response handler for a be_connect message.
-
-        @param msg: message
-        @type  msg: xu message
-        """
-        val = unpackMsg('blkif_be_connect_t', msg)
-        blkif = self.factory.getInstanceByDom(val['domid'])
-        if blkif:
-            blkif.send_fe_interface_status_changed()
-        else:
-            pass
-    
-    def respond_be_vbd_create(self, msg, dev, d):
-        """Response handler for a be_vbd_create message.
-        Tries to grow the vbd, and passes the deferred I{d} on for
-        the grow to call.
-
-        @param msg: message
-        @type  msg: xu message
-        @param dev: device
-        @type  dev: BlkDev
-        @param d: deferred to call
-        @type  d: Deferred
-        """
-        val = unpackMsg('blkif_be_vbd_create_t', msg)
-        blkif = self.factory.getInstanceByDom(val['domid'])
-        if blkif:
-            d1 = defer.Deferred()
-            d1.addCallback(self.respond_be_vbd_grow, dev, d)
-            if d: d1.addErrback(d.errback)
-            blkif.send_be_vbd_grow(val['vdevice'], response=d1)
-        else:
-            pass
-    
-    def respond_be_vbd_grow(self, msg, dev, d):
-        """Response handler for a be_vbd_grow message.
-
-        @param msg: message
-        @type  msg: xu message
-        @param dev: device
-        @type  dev: BlkDev
-        @param d: deferred to call
-        @type  d: Deferred or None
-        """
-        val = unpackMsg('blkif_be_vbd_grow_t', msg)
-       status = val['status']
-       if status != BLKIF_BE_STATUS_OKAY:
-            raise XendError("Adding extent to vbd failed: device %x, error %d"
-                            % (val['extent.device'], status))
-        if d:
-            d.callback(dev)
 
     def recv_be_driver_status_changed(self, msg, req):
         """Request handler for be_driver_status_changed messages.
@@ -101,11 +34,6 @@ class BlkifBackendController(controller.BackendController):
         """
         val = unpackMsg('blkif_be_driver_status_changed_t', msg)
         status = val['status']
-        if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
-            for blkif in self.factory.getInstances():
-                if blkif.backendController == self:
-                    blkif.detach()
 
 class BlkifControllerFactory(controller.SplitControllerFactory):
     """Factory for creating block device interface controllers.
@@ -113,7 +41,6 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
 
     def __init__(self):
         controller.SplitControllerFactory.__init__(self)
-        self.attached = 1
 
     def createInstance(self, dom, recreate=0, backend=0):
         """Create a block device controller for a domain.
@@ -125,20 +52,14 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
         @return: deferred
         @rtype: twisted.internet.defer.Deferred
         """
-        d = defer.Deferred()
         blkif = self.getInstanceByDom(dom)
         if blkif:
+            d = defer.Deferred()
             d.callback(blkif)
         else:
             blkif = BlkifController(self, dom, backend)
             self.addInstance(blkif)
-            if recreate:
-                d.callback(blkif)
-            else:
-                d1 = defer.Deferred()
-                d1.addCallback(blkif.backendController.respond_be_create, d)
-                d1.addErrback(d.errback)
-                blkif.send_be_create(response=d1)
+            d = blkif.connect(recreate=recreate)
         return d
 
     def getDomainDevices(self, dom):
@@ -158,7 +79,7 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
         @param dom: domain
         @type  dom: int
         @param vdev: device index
-        @type  vedv: int
+        @type  vdev: int
         @return: device
         @rtype:  device
         """
@@ -168,66 +89,6 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
     def createBackendController(self, dom):
         return BlkifBackendController(self, dom)
 
-    def setControlDomain(self, dom, recreate=0):
-        """Set the back-end block device controller domain.
-
-        @param dom: domain
-        @type  dom: int
-        @param recreate: if true it's a recreate (after xend restart)
-        @type  recreate: int
-        """
-        if self.dom == dom: return
-        self.deregisterChannel()
-        if not recreate:
-            self.attached = 0
-        self.dom = dom
-        self.registerChannel()
-
-    def getControlDomain(self):
-        """Get the back-end block device controller domain.
-
-        @return: domain
-        @rtype:  int
-        """
-        return self.dom
-
-    def reattachDevice(self, dom, vdev):
-        """Reattach a device (on changing control domain).
-
-        @param dom: domain
-        @type  dom: int
-        @param vdev: device index
-        @type  vdev: int
-        """
-        blkif = self.getInstanceByDom(dom)
-        if blkif:
-            blkif.reattachDevice(vdev)
-        self.attached = self.devicesAttached()
-        if self.attached:
-            self.reattached()
-
-    def devicesAttached(self):
-        """Check if all devices are attached.
-
-        @return: true if all devices attached
-        @rtype:  bool
-        """
-        attached = 1
-        for blkif in self.getInstances():
-            if not blkif.attached:
-                attached = 0
-                break
-        return attached
-                         
-    def reattached(self):
-        """Notify all block interfaces we have been reattached
-        (after changing control domain).
-        """
-        for blkif in self.getInstances():
-            blkif.reattached()
-
-
-
 class BlkDev(controller.Dev):
     """Info record for a block device.
     """
@@ -241,7 +102,9 @@ class BlkDev(controller.Dev):
         self.device = segment['device']
         self.start_sector = segment['start_sector']
         self.nr_sectors = segment['nr_sectors']
-        self.attached = 1
+
+    def getBackendController(self):
+        return self.controller.backendController
 
     def readonly(self):
         return 'w' not in self.mode
@@ -260,7 +123,80 @@ class BlkDev(controller.Dev):
 
     def destroy(self):
         log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
-        self.controller.send_be_vbd_destroy(self.vdev)
+        self.send_be_vbd_destroy()
+
+    def attach(self, d):
+        """Attach the device to its controller.
+
+        @param d: deferred to call with the device on success
+        """
+        d1 = defer.Deferred()
+        d1.addCallback(self.respond_be_vbd_create, d)
+        d1.addErrback(d.errback)
+        self.send_be_vbd_create(response=d1)
+        
+    def send_be_vbd_create(self, response=None):
+        msg = packMsg('blkif_be_vbd_create_t',
+                      { 'domid'        : self.controller.dom,
+                        'blkif_handle' : self.controller.handle,
+                        'vdevice'      : self.vdev,
+                        'readonly'     : self.readonly() })
+        self.getBackendController().writeRequest(msg, response=response)
+        
+    def respond_be_vbd_create(self, msg, d):
+        """Response handler for a be_vbd_create message.
+        Tries to grow the vbd.
+
+        @param msg: message
+        @type  msg: xu message
+        @param d: deferred to call
+        @type  d: Deferred
+        """
+        val = unpackMsg('blkif_be_vbd_create_t', msg)
+        d1 = defer.Deferred()
+        d1.addCallback(self.respond_be_vbd_grow, d)
+        if d: d1.addErrback(d.errback)
+        self.send_be_vbd_grow(response=d1)
+    
+    def send_be_vbd_grow(self, response=None):
+        msg = packMsg('blkif_be_vbd_grow_t',
+                      { 'domid'                : self.controller.dom,
+                        'blkif_handle'         : self.controller.handle,
+                        'vdevice'              : self.vdev,
+                        'extent.device'        : self.device,
+                        'extent.sector_start'  : self.start_sector,
+                        'extent.sector_length' : self.nr_sectors })
+        self.getBackendController().writeRequest(msg, response=response)
+
+    def respond_be_vbd_grow(self, msg, d):
+        """Response handler for a be_vbd_grow message.
+
+        @param msg: message
+        @type  msg: xu message
+        @param d: deferred to call
+        @type  d: Deferred or None
+        """
+        val = unpackMsg('blkif_be_vbd_grow_t', msg)
+       status = val['status']
+       if status != BLKIF_BE_STATUS_OKAY:
+            err = XendError("Adding extent to vbd failed: device %d, error %d"
+                            % (self.vdev, status))
+            #if(d):
+            #    d.errback(err)
+            raise err
+        if d:
+            d.callback(self)
+
+    def send_be_vbd_destroy(self, response=None):
+        log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
+                  self.controller.dom, self.vdev)
+        msg = packMsg('blkif_be_vbd_destroy_t',
+                      { 'domid'                : self.controller.dom,
+                        'blkif_handle'         : self.controller.handle,
+                        'vdevice'              : self.vdev })
+        self.controller.delDevice(self.vdev)
+        self.getBackendController().writeRequest(msg, response=response)
+        
         
 class BlkifController(controller.SplitController):
     """Block device interface controller. Handles all block devices
@@ -268,6 +204,10 @@ class BlkifController(controller.SplitController):
     """
     
     def __init__(self, factory, dom, backend):
+        """Create a block device controller.
+        The controller must be connected using connect() before it can be used.
+        Do not call directly - use createInstance() on the factory instead.
+        """
         controller.SplitController.__init__(self, factory, dom, backend)
         self.devices = {}
         self.addMethod(CMSG_BLKIF_FE,
@@ -276,7 +216,7 @@ class BlkifController(controller.SplitController):
         self.addMethod(CMSG_BLKIF_FE,
                        CMSG_BLKIF_FE_INTERFACE_CONNECT,
                        self.recv_fe_interface_connect)
-        self.attached = 1
+        self.handle = 0
         self.evtchn = None
         self.registerChannel()
 
@@ -311,6 +251,10 @@ class BlkifController(controller.SplitController):
         self.devices[vdev] = dev
         return dev
 
+    def delDevice(self, vdev):
+        if vdev in self.devices:
+            del self.devices[vdev]
+
     def attachDevice(self, vdev, mode, segment, recreate=0):
         """Attach a device to the specified interface.
         On success the returned deferred will be called with the device.
@@ -332,63 +276,75 @@ class BlkifController(controller.SplitController):
         if recreate:
             d.callback(dev)
         else:
-            d1 = defer.Deferred()
-            d1.addCallback(self.backendController.respond_be_vbd_create, dev, d)
-            d1.addErrback(d.errback)
-            self.send_be_vbd_create(vdev, response=d1)
+            dev.attach(d)
         return d
 
     def destroy(self):
-        def cb_destroy(val):
-            self.send_be_destroy()
+        """Destroy the controller and all devices.
+        """
         log.debug("Destroying blkif domain=%d", self.dom)
-        d = defer.Deferred()
-        d.addCallback(cb_destroy)
-        self.send_be_disconnect(response=d)
+        self.destroyDevices()
+        self.disconnect()
 
     def destroyDevices(self):
+        """Destroy all devices.
+        """
         for dev in self.getDevices():
             dev.destroy()
 
-    def detach(self):
-        """Detach all devices, when the back-end control domain has changed.
-        """
-        self.attached = 0
-        for dev in self.devices.values():
-            dev.attached = 0
-            d1 = defer.Deferred()
-            d1.addCallback(self.backendController.respond_be_vbd_create, None, None)
-            self.send_be_vbd_create(vdev, response=d1)
-
-    def reattachDevice(self, vdev):
-        """Reattach a device, when the back-end control domain has changed.
+    def connect(self, recreate=0):
+        """Connect the controller to the blkif control interface.
+
+        @param recreate: true if after xend restart
+        @return: deferred
         """
-        dev = self.devices[vdev]
-        dev.attached = 1
-        attached = 1
-        for dev in self.devices.values():
-            if not dev.attached:
-                attached = 0
-                break
-        self.attached = attached
-        return self.attached
-
-    def reattached(self):
-        """All devices have been reattached after the back-end control
-        domain has changed.
+        log.debug("Connecting blkif domain=%d", self.dom)
+        d = defer.Deferred()
+        if recreate:
+            d.callback(self)
+        else:
+            def cbresp(msg):
+                return self
+            d.addCallback(cbresp)
+            self.send_be_create(response=d)
+        return d
+        
+    def send_be_create(self, response=None):
+        msg = packMsg('blkif_be_create_t',
+                      { 'domid'        : self.dom,
+                        'blkif_handle' : self.handle })
+        self.backendController.writeRequest(msg, response=response)
+    
+    def disconnect(self):
+        """Disconnect from the blkif control interface and destroy it.
         """
-        msg = packMsg('blkif_fe_interface_status_changed_t',
-                      { 'handle' : 0,
-                        'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED})
-        self.writeRequest(msg)
+        def cb_destroy(val):
+            self.send_be_destroy()
+        d = defer.Deferred()
+        d.addCallback(cb_destroy)
+        self.send_be_disconnect(response=d)
+        
+    def send_be_disconnect(self, response=None):
+        log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
+        msg = packMsg('blkif_be_disconnect_t',
+                      { 'domid'        : self.dom,
+                        'blkif_handle' : self.handle })
+        self.backendController.writeRequest(msg, response=response)
 
+    def send_be_destroy(self, response=None):
+        log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
+        msg = packMsg('blkif_be_destroy_t',
+                      { 'domid'        : self.dom,
+                        'blkif_handle' : self.handle })
+        self.backendController.writeRequest(msg, response=response)
+        
     def recv_fe_driver_status_changed(self, msg, req):
         msg = packMsg('blkif_fe_interface_status_changed_t',
-                      { 'handle' : 0,
+                      { 'handle' : self.handle,
                         'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
                         'evtchn' : 0 })
         self.writeRequest(msg)
-    
+
     def recv_fe_interface_connect(self, msg, req):
         val = unpackMsg('blkif_fe_interface_connect_t', msg)
         self.evtchn = channel.eventChannel(0, self.dom)
@@ -400,63 +356,23 @@ class BlkifController(controller.SplitController):
                         'evtchn'       : self.evtchn['port1'],
                         'shmem_frame'  : val['shmem_frame'] })
         d = defer.Deferred()
-        d.addCallback(self.backendController.respond_be_connect)
+        d.addCallback(self.respond_be_connect)
         self.backendController.writeRequest(msg, response=d)
 
+    def respond_be_connect(self, msg):
+        """Response handler for a be_connect message.
+
+        @param msg: message
+        @type  msg: xu message
+        """
+        val = unpackMsg('blkif_be_connect_t', msg)
+        self.send_fe_interface_status_changed()
+            
     def send_fe_interface_status_changed(self, response=None):
         msg = packMsg('blkif_fe_interface_status_changed_t',
-                      { 'handle' : 0,
+                      { 'handle' : self.handle,
                         'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
                         'evtchn' : self.evtchn['port2'] })
         self.writeRequest(msg, response=response)
-
-    def send_be_create(self, response=None):
-        msg = packMsg('blkif_be_create_t',
-                      { 'domid'        : self.dom,
-                        'blkif_handle' : 0 })
-        self.backendController.writeRequest(msg, response=response)
-
-    def send_be_disconnect(self, response=None):
-        log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
-        msg = packMsg('blkif_be_disconnect_t',
-                      { 'domid'        : self.dom,
-                        'blkif_handle' : 0 })
-        self.backendController.writeRequest(msg, response=response)
-
-    def send_be_destroy(self, response=None):
-        log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
-        msg = packMsg('blkif_be_destroy_t',
-                      { 'domid'        : self.dom,
-                        'blkif_handle' : 0 })
-        self.backendController.writeRequest(msg, response=response)
-
-    def send_be_vbd_create(self, vdev, response=None):
-        dev = self.devices[vdev]
-        msg = packMsg('blkif_be_vbd_create_t',
-                      { 'domid'        : self.dom,
-                        'blkif_handle' : 0,
-                        'vdevice'      : dev.vdev,
-                        'readonly'     : dev.readonly() })
-        self.backendController.writeRequest(msg, response=response)
-        
-    def send_be_vbd_grow(self, vdev, response=None):
-        dev = self.devices[vdev]
-        msg = packMsg('blkif_be_vbd_grow_t',
-                      { 'domid'                : self.dom,
-                        'blkif_handle'         : 0,
-                        'vdevice'              : dev.vdev,
-                        'extent.device'        : dev.device,
-                        'extent.sector_start'  : dev.start_sector,
-                        'extent.sector_length' : dev.nr_sectors })
-        self.backendController.writeRequest(msg, response=response)
-
-    def send_be_vbd_destroy(self, vdev, response=None):
-        log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
-        dev = self.devices[vdev]
-        msg = packMsg('blkif_be_vbd_destroy_t',
-                      { 'domid'                : self.dom,
-                        'blkif_handle'         : 0,
-                        'vdevice'              : dev.vdev })
-        del self.devices[vdev]
-        self.backendController.writeRequest(msg, response=response)
     
+
index d78ba252cb782caab70b6469ed31c15a4d3354db..4c6dbadd17e8d321a5d19b5ef81ef92ddca95449 100755 (executable)
@@ -333,13 +333,15 @@ class Channel(BaseChannel):
         (ty, subty) = self.getMessageType(msg)
         #todo:  Must respond before writing any more messages.
         #todo:  Should automate this (respond on write)
-        self.port.write_response(msg)
+        responded = 0
         dev = self.getDevice(ty)
         if dev:
-            dev.requestReceived(msg, ty, subty)
+            responded = dev.requestReceived(msg, ty, subty)
         else:
             print ("requestReceived> No device: Message type %s %d:%d"
                    % (msgTypeName(ty, subty), ty, subty)), self
+        if not responded:
+            self.port.write_response(msg)
 
     def handleResponses(self):
         work = 0
index cea9c38dfb05b0836b0efca13195395b1e11c030..28662207bbfe91f2d978a61e81ff747f7025b03b 100755 (executable)
@@ -125,12 +125,14 @@ class CtrlMsgRcvr:
         if DEBUG:
             print 'requestReceived>',
             printMsg(msg, all=1)
+        responded = 0
         method = self.getMethod(type, subtype)
         if method:
-            method(msg, 1)
+            responded = method(msg, 1)
         elif DEBUG:
             print ('requestReceived> No handler: Message type %s %d:%d'
                    % (msgTypeName(type, subtype), type, subtype)), self
+        return responded
         
     def responseReceived(self, msg, type, subtype):
         """Dispatch a response to handlers.
index e966ec9003c5b71615cd960f10d10b3a231996b3..8d68d95887c3c611069d5aed9649177132c56920 100644 (file)
@@ -215,7 +215,7 @@ def packMsg(ty, params):
         else:
             args[k] = v
     msg = xu.message(major, minor, msgid, args)
-    if DEBUG: print '<packMsg', msg.get_header()['id'], ty, params
+    if DEBUG: print '<packMsg', msg.get_header()['id'], ty, args
     return msg
 
 def unpackMsg(ty, msg):
@@ -231,8 +231,9 @@ def unpackMsg(ty, msg):
     @rtype: dict
     """
     args = msg.get_payload()
+    if DEBUG: print '>unpackMsg', args
     if isinstance(args, types.StringType):
-        args = { 'value': args }
+        args = {'value': args}
     else:
         mac = [0, 0, 0, 0, 0, 0]
         macs = []
@@ -284,5 +285,5 @@ def printMsg(msg, out=sys.stdout, all=0):
     ty = msgTypeName(major, minor)
     print >>out, 'message:', 'type=', ty, '%d:%d' % (major, minor), 'id=%d' % msgid
     if all:
-        print >>out, 'payload=', unpackMsg(ty, msg)
+        print >>out, 'payload=', msg.get_payload()
 
index f4247c670f620033159b7cf720f02025d09e6aee..a5add8e7fb4ce931a02718d9630013b8a87040d8 100755 (executable)
@@ -27,30 +27,11 @@ class NetifBackendController(controller.BackendController):
         self.addMethod(CMSG_NETIF_BE,
                        CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
                        self.recv_be_driver_status_changed)
-        self.attached = 1
         self.registerChannel()
 
-    def respond_be_connect(self, msg):
-        val = unpackMsg('netif_be_connect_t', msg)
-        dom = val['domid']
-        vif = val['netif_handle']
-        netif = self.factory.getInstanceByDom(dom)
-        if netif:
-            netif.send_interface_connected(vif)
-        else:
-            log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
-            pass
-
     def recv_be_driver_status_changed(self, msg, req):
         val = unpackMsg('netif_be_driver_status_changed_t', msg)
         status = val['status']
-        if status == NETIF_DRIVER_STATUS_UP and not self.attached:
-            # If we are not attached the driver domain was changed, and
-            # this signals the new driver domain is ready.
-            for netif in self.factory.getInstances():
-                if netif.backendController == self:
-                    netif.reattach_devices()
-            self.attached = 1
 
 class NetifControllerFactory(controller.SplitControllerFactory):
     """Factory for creating network interface controllers.
@@ -58,7 +39,6 @@ class NetifControllerFactory(controller.SplitControllerFactory):
 
     def __init__(self):
         controller.ControllerFactory.__init__(self)
-        self.attached = 1
 
     def createInstance(self, dom, recreate=0, backend=0):
         """Create or find the network interface controller for a domain.
@@ -95,26 +75,6 @@ class NetifControllerFactory(controller.SplitControllerFactory):
     def createBackendController(self, dom):
         return NetifBackendController(self, dom)
 
-    def setControlDomain(self, dom, recreate=0):
-        """Set the 'back-end' device driver domain.
-
-        @param dom:     domain
-        @param recreate: if true this is a recreate (xend restarted)
-        """
-        if self.dom == dom: return
-        self.deregisterChannel()
-        if not recreate:
-            self.attached = 0
-        self.dom = dom
-        self.registerChannel()
-
-    def getControlDomain(self):
-        """Get the domain id of the back-end control domain.
-
-        @return domain id
-        """
-        return self.dom
-
 class NetDev(controller.Dev):
     """Info record for a network device.
     """
@@ -125,6 +85,9 @@ class NetDev(controller.Dev):
         self.evtchn = None
         self.configure(config)
 
+    def getBackendController(self):
+        return self.controller.backendController
+
     def configure(self, config):
         self.config = config
         self.mac = None
@@ -205,19 +168,76 @@ class NetDev(controller.Dev):
         if vnet:
             vnet.vifctl(op, self.get_vifname(), self.get_mac())
 
+    def attach(self, d):
+        print 'attach>', d
+        self.send_be_create(response=d)
+
+    def send_be_create(self, response=None):
+        msg = packMsg('netif_be_create_t',
+                      { 'domid'        : self.controller.dom,
+                        'netif_handle' : self.vif,
+                        'mac'          : self.mac })
+        self.getBackendController().writeRequest(msg, response=response)
+
     def destroy(self):
         """Destroy the device's resources and disconnect from the back-end
         device controller.
         """
         def cb_destroy(val):
-            self.controller.send_be_destroy(self.vif)
+            self.send_be_destroy()
         log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
         self.vifctl('down')
         d = defer.Deferred()
         d.addCallback(cb_destroy)
-        self.controller.send_be_disconnect(self.vif, response=d)
+        self.send_be_disconnect(response=d)
+
+    def send_be_disconnect(self, response=None):
+        msg = packMsg('netif_be_disconnect_t',
+                      { 'domid'        : self.controller.dom,
+                        'netif_handle' : self.vif })
+        self.getBackendController().writeRequest(msg, response=response)
+
+    def send_be_destroy(self, response=None):
+        msg = packMsg('netif_be_destroy_t',
+                      { 'domid'        : self.controller.dom,
+                        'netif_handle' : self.vif })
+        self.controller.delDevice(self.vif)
+        self.getBackendController().writeRequest(msg, response=response)
+    
+    def recv_fe_interface_connect(self, val, req):
+        if not req: return
+        self.evtchn = channel.eventChannel(0, self.controller.dom)
+        msg = packMsg('netif_be_connect_t',
+                      { 'domid'          : self.controller.dom,
+                        'netif_handle'   : self.vif,
+                        'evtchn'         : self.evtchn['port1'],
+                        'tx_shmem_frame' : val['tx_shmem_frame'],
+                        'rx_shmem_frame' : val['rx_shmem_frame'] })
+        d = defer.Deferred()
+        d.addCallback(self.respond_be_connect)
+        self.getBackendController().writeRequest(msg, response=d)
         
+    def respond_be_connect(self, msg):
+        val = unpackMsg('netif_be_connect_t', msg)
+        dom = val['domid']
+        vif = val['netif_handle']
+        print 'respond_be_connect>', '     dom=', dom, '     vif=', vif
+        print 'respond_be_connect>', 'self.dom=', self.controller.dom, 'self.vif=', self.vif
+        msg = packMsg('netif_fe_interface_status_changed_t',
+                      { 'handle' : self.vif,
+                        'status' : NETIF_INTERFACE_STATUS_CONNECTED,
+                        'evtchn' : self.evtchn['port2'],
+                        'mac'    : self.mac })
+        self.controller.writeRequest(msg)
 
+    def attach_fe_device(self):
+        msg = packMsg('netif_fe_interface_status_changed_t',
+                      { 'handle' : self.vif,
+                        'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
+                        'evtchn' : 0,
+                        'mac'    : self.mac })
+        self.controller.writeRequest(msg)
+        
 class NetifController(controller.SplitController):
     """Network interface controller. Handles all network devices for a domain.
     """
@@ -266,6 +286,10 @@ class NetifController(controller.SplitController):
         self.devices[vif] = dev
         return dev
 
+    def delDevice(self, vif):
+        if vif in self.devices:
+            del self.devices[vif]
+
     def destroy(self):
         """Destroy the controller and all devices.
         """
@@ -285,79 +309,29 @@ class NetifController(controller.SplitController):
         @param recreate: recreate flag (true after xend restart)
         @return: deferred
         """
-        self.addDevice(vif, config)
+        dev = self.addDevice(vif, config)
         d = defer.Deferred()
         if recreate:
             d.callback(self)
         else:
-            self.send_be_create(vif, response=d)
+            dev.attach(d)
         return d
 
-    def reattach_devices(self):
-        """Reattach all devices when the back-end control domain has changed.
-        """
-        self.send_be_create(vif)
-        self.attach_fe_devices()
-
-    def attach_fe_devices(self):
-        for dev in self.devices.values():
-            msg = packMsg('netif_fe_interface_status_changed_t',
-                          { 'handle' : dev.vif,
-                            'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
-                            'evtchn' : 0,
-                            'mac'    : dev.mac })
-            self.writeRequest(msg)
-    
     def recv_fe_driver_status_changed(self, msg, req):
         if not req: return
         msg = packMsg('netif_fe_driver_status_changed_t',
                       { 'status'        : NETIF_DRIVER_STATUS_UP,
                         'nr_interfaces' : len(self.devices) })
         self.writeRequest(msg)
-        self.attach_fe_devices()
-
+        for dev in self.devices.values():
+            dev.attach_fe_device()
+    
     def recv_fe_interface_connect(self, msg, req):
         val = unpackMsg('netif_fe_interface_connect_t', msg)
-        dev = self.devices[val['handle']]
-        dev.evtchn = channel.eventChannel(0, self.dom)
-        msg = packMsg('netif_be_connect_t',
-                      { 'domid'          : self.dom,
-                        'netif_handle'   : dev.vif,
-                        'evtchn'         : dev.evtchn['port1'],
-                        'tx_shmem_frame' : val['tx_shmem_frame'],
-                        'rx_shmem_frame' : val['rx_shmem_frame'] })
-        d = defer.Deferred()
-        d.addCallback(self.backendController.respond_be_connect)
-        self.backendController.writeRequest(msg, response=d)
-
-    def send_interface_connected(self, vif, response=None):
-        dev = self.devices[vif]
-        msg = packMsg('netif_fe_interface_status_changed_t',
-                      { 'handle' : dev.vif,
-                        'status' : NETIF_INTERFACE_STATUS_CONNECTED,
-                        'evtchn' : dev.evtchn['port2'],
-                        'mac'    : dev.mac })
-        self.writeRequest(msg, response=response)
-
-    def send_be_create(self, vif, response=None):
-        dev = self.devices[vif]
-        msg = packMsg('netif_be_create_t',
-                      { 'domid'        : self.dom,
-                        'netif_handle' : dev.vif,
-                        'mac'          : dev.mac })
-        self.backendController.writeRequest(msg, response=response)
-
-    def send_be_disconnect(self, vif, response=None):
-        dev = self.devices[vif]
-        msg = packMsg('netif_be_disconnect_t',
-                      { 'domid'        : self.dom,
-                        'netif_handle' : dev.vif })
-        self.backendController.writeRequest(msg, response=response)
+        vif = val['handle']
+        dev = self.devices.get(vif)
+        if dev:
+            dev.recv_fe_interface_connect(val, req)
+        else:
+            log.error('Received netif_fe_interface_connect for unknown vif: '+vif)
 
-    def send_be_destroy(self, vif, response=None):
-        dev = self.devices[vif]
-        del self.devices[vif]
-        msg = packMsg('netif_be_destroy_t',
-                      { 'domid'        : self.dom,
-                        'netif_handle' : vif })
-        self.backendController.writeRequest(msg, response=response)